﻿using System;
using System.Collections.Generic;
using System.Linq;
using Granite.Modeling;
using Granite.Metadata;
using Granite.Modeling.Internals;

namespace Rifts.Models.Characters
{
	public class WeaponProficiency : ChangeTrackingModelBase, IAttributeClass
	{
		public string Name
		{
			get { return Get<string>("Name"); }
			set { Set(value, "Name"); }
		}

		public int? MeleeStrike
		{
			get { return Get<int?>("MeleeStrike"); }
			set { Set(value, "MeleeStrike"); }
		}

		public int? ThrownStrike
		{
			get { return Get<int?>("ThrownStrike"); }
			set { Set(value, "ThrownStrike"); }
		}

		public int? RangedStrike
		{
			get { return Get<int?>("RangedStrike"); }
			set { Set(value, "RangedStrike"); }
		}

		public int? Parry
		{
			get { return Get<int?>("Parry"); }
			set { Set(value, "Parry"); }
		}

		public int? Entangle
		{
			get { return Get<int?>("Entangle"); }
			set { Set(value, "Entangle"); }
		}

		public int? Disarm
		{
			get { return Get<int?>("Disarm"); }
			set { Set(value, "Disarm"); }
		}

		public int? Damage
		{
			get { return Get<int?>("Damage"); }
			set { Set(value, "Damage"); }
		}

		public AbilityCollection Abilities
		{
			get { return GetNew<AbilityCollection>("Abilities"); }
		}

		public void BumpAttribute(string attributeName, int value)
		{
			var propertyName = MapAttribute(attributeName);

			var oldValue = GetAttribute(propertyName);
			var newValue = (oldValue ?? 0) + value;
			Properties.Set(newValue, PropertySetModes.FixCasing | PropertySetModes.RaiseChangedEvent | PropertySetModes.ValidateProperty | PropertySetModes.ValidateObject, propertyName);
		}

		internal int? GetAttribute(string attributeName)
		{
			var propertyName = MapAttribute(attributeName);
			var oldValue = (int?)Properties.Metadata.Properties[propertyName].InvokeGet(this);
			return oldValue;
		}

		static string MapAttribute(string attributeName)
		{
			if (s_AttributeList.Contains(attributeName) && s_AttributeList[attributeName].CanWrite)
				return attributeName;

			string baseProperty = attributeName + "Base";
			if (s_AttributeList.Contains(baseProperty) && s_AttributeList[baseProperty].CanWrite)
				return baseProperty;

			return attributeName; //the error will be handled elsewhere
		}

		public void SetAttribute(string attributeName, int value)
		{
			var propertyName = MapAttribute(attributeName);

			if (Properties.Metadata.Properties.Contains(propertyName))
				Properties.Set(value, PropertySetModes.FixCasing | PropertySetModes.RaiseChangedEvent | PropertySetModes.ValidateProperty | PropertySetModes.ValidateObject, propertyName);
		}

		readonly static PropertyMetadataCollection s_AttributeList = MetadataCache.GetMetadata(typeof(WeaponProficiency)).Properties;
	}

}
